var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

import React, { Component, cloneElement, Children } from 'react';
import PropTypes from 'prop-types';

import './Navigator.css';

/* 
# Sole
为内容创建带有唯一标识符的对象；

该对象有以下属性：
key : number    //唯一标识符，每次创建都不一样，即使用相同的值初创建也是如此；
value : any     //创建该对象时传的值
*/

var Sole = function Sole(value) {
    _classCallCheck(this, Sole);

    this.value = value;
    var currentDate = new Date();
    this.key = currentDate.getTime() + Math.random();
};

/* 
# NavConfiger
设置 Navigator 的桥梁；

在子组件的 context 中 注入了以下方法；

- 为使用者提供的方法：
   pushNavConfig : (navConfig)-> configId      //往导航条配置栈中推入一个导航条的配置对象 navConfig，并返回配置id，该 id 可用于通过 popNavConfig 方法推出该 id  对应的配置对象；
   popNavConfig : (configId)->void     //从导航条配置栈中推出 configId 对应的配置对象；configId 是 执行 pushNavConfig 方法的返回值；

- 为 Navigator 提供的方法：
   pushNavigator : (navigator)-> navID      //往导航条栈中推入一个 Navigator 实例，并返回一个 navID
   popNavigator : (navID)->void        //从导航条栈中推出 navID 对应的 Navigator 实例

*/


var NavConfiger = function (_Component) {
    _inherits(NavConfiger, _Component);

    function NavConfiger(props) {
        _classCallCheck(this, NavConfiger);

        var _this = _possibleConstructorReturn(this, (NavConfiger.__proto__ || Object.getPrototypeOf(NavConfiger)).call(this, props));

        _this.navSoleList = [];


        _this.pushNavigator = _this.pushNavigator.bind(_this);
        _this.popNavigator = _this.popNavigator.bind(_this);

        _this.pushNavConfig = _this.pushNavConfig.bind(_this);
        _this.popNavConfig = _this.popNavConfig.bind(_this);
        return _this;
    }

    _createClass(NavConfiger, [{
        key: 'getChildContext',
        value: function getChildContext() {

            return {
                pushNavConfig: this.pushNavConfig,
                popNavConfig: this.popNavConfig,

                pushNavigator: this.pushNavigator,
                popNavigator: this.popNavigator
            };
        }
    }, {
        key: 'pushNavigator',
        value: function pushNavigator(navigator) {
            var navSole = new Sole(navigator);
            this.navSoleList.push(navSole);
            // this.forceUpdate();

            return navSole.key;
        }
    }, {
        key: 'popNavigator',
        value: function popNavigator(navID) {
            var navSoleList = this.navSoleList;
            var deleIndex = navSoleList.findIndex(function (sole) {
                return sole.key == navID;
            });
            this.navSoleList.splice(deleIndex, 1);
            // this.forceUpdate();
        }
    }, {
        key: 'pushNavConfig',
        value: function pushNavConfig(navConfig) {
            var currentNavSole = this.currentNavSole;
            var currentNav = currentNavSole.value;
            var configKey = currentNav.pushNavConfig(navConfig);

            var configID = {
                navKey: currentNavSole.key,
                configKey: configKey
            };

            return configID;
        }
    }, {
        key: 'popNavConfig',
        value: function popNavConfig(configID) {
            var navKey = configID.navKey;

            var navSoleList = this.navSoleList;
            var navSole = navSoleList.find(function (sole) {
                return sole.key == navKey;
            });

            if (navSole) {
                var nav = navSole.value;
                nav.popNavConfig(configID.configKey);
            }
        }
    }, {
        key: 'render',
        value: function render() {
            return this.props.children;
        }
    }, {
        key: 'currentNavSole',
        get: function get() {
            var navSoleList = this.navSoleList;
            var soleCount = navSoleList.length;
            var currentIndex = soleCount - 1;
            var currentSole = navSoleList[currentIndex];

            if (!currentSole) {
                throw new Error("没有找到 Navigator 实例；请确保在 Navigator 实例创建之后，再执行与 Navigator 相关的操作！");
            }

            return currentSole;
        }
    }]);

    return NavConfiger;
}(Component);

/* 
# Navigator 导航条

## props
navConfig ：{
    hide ?: boolean,    // 设置是否显示 导航条
    left ?: string || element,      //设置leftItem 
    center ?: string || element,    //设置centerItem
    right: ?: string || element,    //设置rightItem
    leftAction ?: function,      //设置 leftItem 的 click 事件处理函数
    rightAction ?: function,    //设置 rightItem 的 click 事件处理函数
    navClass ?: string,         //设置 navArea 的 css 类
    leftAreaClass ?: string,    //设置 leftArea 的 css 类
    centerAreaClass ?: string,  //设置 centerClass 的 css 类
    rightAreaClass ?: string,   //设置 rightArea 的 csss 类
}       //配置导航条

## 其它 prop
Navigator 会把其它的 props 设置到 Navigator 的根元素上，即: navArea ; 所以，给 Navigator 设置 以下 prop 会直接设置在 navArea 上；

className ?: string    //设置 navArea 的 css 类
style ?: StyleObject    //设置 navArea 的内联样式对象


*/


NavConfiger.childContextTypes = {
    pushNavConfig: PropTypes.func,
    popNavConfig: PropTypes.func,
    pushNavigator: PropTypes.func,
    popNavigator: PropTypes.func
};

var Navigator = function (_Component2) {
    _inherits(Navigator, _Component2);

    _createClass(Navigator, [{
        key: 'currentNavConfig',
        get: function get() {
            var navConfigSoleList = this.navConfigSoleList;
            var currentSole = navConfigSoleList[navConfigSoleList.length - 1];
            return currentSole && currentSole.value || this.props.navConfig;
        }
    }]);

    function Navigator(props) {
        _classCallCheck(this, Navigator);

        var _this2 = _possibleConstructorReturn(this, (Navigator.__proto__ || Object.getPrototypeOf(Navigator)).call(this, props));

        _this2.navConfigSoleList = [];
        _this2.defaultNavConfig = {
            left: React.createElement('p', { className: 'left_item', onClick: _this2.backClickHandle })
        };

        _this2.backClickHandle = _this2.backClickHandle.bind(_this2);
        return _this2;
    }

    _createClass(Navigator, [{
        key: 'componentWillMount',
        value: function componentWillMount() {
            this.navID = this.context.pushNavigator(this);
        }
    }, {
        key: 'componentWillUnmount',
        value: function componentWillUnmount() {
            this.context.popNavigator(this.navID);
        }
    }, {
        key: 'pushNavConfig',
        value: function pushNavConfig(navConfig) {
            var navConfigSole = new Sole(navConfig);
            this.navConfigSoleList.push(navConfigSole);
            this.forceUpdate();

            return navConfigSole.key;
        }
    }, {
        key: 'popNavConfig',
        value: function popNavConfig(configKey) {
            var navConfigSoleList = this.navConfigSoleList;
            var deleIndex = navConfigSoleList.findIndex(function (sole) {
                return sole.key == configKey;
            });

            if (deleIndex < 0) {
                throw new Error("没有找到 navConfig ；你可能过度执行 popNavConfig 方法 或者 没有给 popNavConfig 方法传入正确的 configID，请确保操作 popNavConfig 与 pushNavConfig 一一 对应 ！");
            }

            this.navConfigSoleList.splice(deleIndex, 1);
            this.forceUpdate();
        }
    }, {
        key: 'backClickHandle',
        value: function backClickHandle() {
            window.history.back();
        }
    }, {
        key: 'passNavItems',
        value: function passNavItems(navConfig) {
            var left = navConfig.left,
                center = navConfig.center,
                right = navConfig.right,
                _navConfig$leftAction = navConfig.leftAction,
                leftAction = _navConfig$leftAction === undefined ? this.backClickHandle : _navConfig$leftAction,
                rightAction = navConfig.rightAction;


            var leftItem = left;
            var centerItem = this.passCenterItem(center);
            var rightItem = right;

            if (left && typeof left == "string") {

                leftItem = React.createElement(
                    'p',
                    { className: 'left_item', onClick: leftAction },
                    left
                );
            }

            if (right && typeof right == "string") {

                rightItem = React.createElement(
                    'p',
                    { className: 'right_item', onClick: rightAction },
                    right
                );
            }

            return { left: leftItem, center: centerItem, right: rightItem };
        }
    }, {
        key: 'passCenterItem',
        value: function passCenterItem(centerConfig) {

            var centerItem = centerConfig;

            if (centerConfig && typeof centerConfig == "string") {

                centerItem = React.createElement(
                    'p',
                    { className: 'center_item' },
                    centerConfig
                );
            }

            return centerItem;
        }
    }, {
        key: 'render',
        value: function render() {
            var _props = this.props,
                children = _props.children,
                className = _props.className,
                style = _props.style,
                navConfig = _props.navConfig,
                otherProps = _objectWithoutProperties(_props, ['children', 'className', 'style', 'navConfig']);

            var currentNavConfig = this.currentNavConfig;
            var finalNavConfig = this.finalNavConfig;

            var childCount = Children.count(children);

            var leftItem = null;
            var centerItem = null;
            var rightItem = null;

            switch (childCount) {
                case 1:
                    return cloneElement(children, { navConfig: currentNavConfig });

                case 3:
                    {

                        var navItems = Children.map(children, function (element, index) {

                            switch (index) {
                                case 0:
                                    return cloneElement(element, { navConfig: currentNavConfig });
                                case 1:
                                    return cloneElement(element, { navConfig: currentNavConfig });
                                case 2:
                                    return cloneElement(element, { navConfig: currentNavConfig });
                            }
                        });

                        leftItem = navItems[0];
                        centerItem = navItems[1];
                        rightItem = navItems[2];

                        break;
                    }

                case 2:
                    {

                        var _navItems = Children.map(children, function (element, index) {

                            switch (index) {
                                case 0:
                                    return cloneElement(element, { navConfig: currentNavConfig });
                                case 1:
                                    return cloneElement(element, { navConfig: currentNavConfig });
                            }
                        });

                        var centerConfig = currentNavConfig && currentNavConfig.center;

                        leftItem = _navItems[0];
                        centerItem = this.passCenterItem(centerConfig);
                        rightItem = _navItems[1];

                        break;
                    }

                default:
                    {
                        var _navItems2 = this.passNavItems(finalNavConfig);
                        leftItem = _navItems2.left;
                        centerItem = _navItems2.center;
                        rightItem = _navItems2.right;
                    }

            }

            var navClass = finalNavConfig.navClass,
                leftAreaClass = finalNavConfig.leftAreaClass,
                centerAreaClass = finalNavConfig.centerAreaClass,
                rightAreaClass = finalNavConfig.rightAreaClass,
                hide = finalNavConfig.hide;


            var rootClass = 'navigator ' + className + ' ' + navClass;

            var rootDisplay = hide ? { display: "none" } : {};
            var rootStyle = Object.assign({}, style, rootDisplay);

            return React.createElement(
                'div',
                Object.assign({ className: rootClass, style: rootStyle }, otherProps),
                React.createElement(
                    'div',
                    { className: 'left ' + leftAreaClass },
                    leftItem
                ),
                React.createElement(
                    'div',
                    { className: 'center ' + centerAreaClass },
                    centerItem
                ),
                React.createElement(
                    'div',
                    { className: 'right  ' + rightAreaClass },
                    rightItem
                )
            );
        }
    }, {
        key: 'finalNavConfig',
        get: function get() {
            return this.currentNavConfig || this.defaultNavConfig;
        }
    }]);

    return Navigator;
}(Component);

Navigator.contextTypes = {
    pushNavigator: PropTypes.func,
    popNavigator: PropTypes.func
};


export { NavConfiger, Navigator, Sole };
